default_platform(:android)
fastlane_require 'dotenv'

SUPPORTED_LOCALES = [
  { glotpress: "ar", google_play: "ar",  promo_config: {}},
  { glotpress: "de", google_play: "de-DE",  promo_config: {} },
  { glotpress: "en-gb", google_play: "en-US",  promo_config: {} },
  { glotpress: "es", google_play: "es-ES",  promo_config: {} },
  { glotpress: "fr", google_play: "fr-CA",  promo_config: false },
  { glotpress: "fr", google_play: "fr-FR",  promo_config: {} },
  { glotpress: "he", google_play: "iw-IL",  promo_config: {} },
  { glotpress: "id", google_play: "id",  promo_config: {} },
  { glotpress: "it", google_play: "it-IT",  promo_config: {} },
  { glotpress: "ja", google_play: "ja-JP",  promo_config: {} },
  { glotpress: "ko", google_play: "ko-KR",  promo_config: {} },
  { glotpress: "nl", google_play: "nl-NL",  promo_config: {} },
  { glotpress: "pl", google_play: "pl-PL",  promo_config: {} },
  { glotpress: "pt-br", google_play: "pt-BR",  promo_config: {} },
  { glotpress: "ru", google_play: "ru-RU",  promo_config: {} },
  { glotpress: "sr", google_play:  "sr",  promo_config: false },
  { glotpress: "sv", google_play: "sv-SE",  promo_config: {} },
  { glotpress: "th", google_play: "th",  promo_config: {} },
  { glotpress: "tr", google_play: "tr-TR",  promo_config: {} },
  { glotpress: "vi", google_play: "vi",  promo_config: {} },
  { glotpress: "zh-cn", google_play: "zh-CN",  promo_config: {} },
  { glotpress: "zh-tw", google_play: "zh-TW",  promo_config: {} },
].freeze

platform :android do
########################################################################
# Includes
########################################################################
import "./ScreenshotFastfile"

# Environment
########################################################################
Dotenv.load('~/.wpandroid-env.default')
ENV[GHHELPER_REPO="wordpress-mobile/WordPress-Android"]
ENV["PROJECT_ROOT_FOLDER"]="./"
ENV["PROJECT_NAME"]="WordPress"
ENV["HAS_ALPHA_VERSION"]="true"

########################################################################
# Release Lanes
########################################################################
#####################################################################################
  # code_freeze
  # -----------------------------------------------------------------------------------
  # This lane executes the steps planned on code freeze
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane code_freeze [update_release_branch_version:<update flag>] [skip_confirm:<skip confirm>]
  #
  # Example:
  # bundle exec fastlane code_freeze 
  # bundle exec fastlane code_freeze update_release_branch_version:false
  # bundle exec fastlane code_freeze skip_confirm:true
  #####################################################################################
  desc "Creates a new release branch from the current develop"
  lane :code_freeze do | options |
    old_version = android_codefreeze_prechecks(options)
   
    android_bump_version_release()
    new_version = android_get_app_version()
    android_update_release_notes(new_version: new_version)
    setbranchprotection(repository:GHHELPER_REPO, branch: "release/#{new_version}")
    setfrozentag(repository:GHHELPER_REPO, milestone: new_version)
    
    localize_libs()
    android_tag_build()
    get_prs_list(repository:GHHELPER_REPO, start_tag:"release/#{old_version}", report_path:"#{File.expand_path('~')}/wpandroid_prs_list_#{old_version}_#{new_version}.txt")
  end

#####################################################################################
# update_appstore_strings 
# -----------------------------------------------------------------------------------
# This lane gets the data from the txt files in the WordPress/metadata/ folder
# and updates the .po file that is then picked by GlotPress for translations.
# -----------------------------------------------------------------------------------
# Usage:
# fastlane update_appstore_strings version:<version>
#
# Example:
# fastlane update_appstore_strings version:10.3
#####################################################################################
  desc "Updates the PlayStoreStrings.po file"
  lane :update_appstore_strings do |options| 
    prj_folder = Dir.pwd + "/.."

    files = {
      release_note: prj_folder + "/WordPress/metadata/release_notes.txt",
      play_store_promo: prj_folder + "/WordPress/metadata/short_description.txt",
      play_store_desc: prj_folder + "/WordPress/metadata/full_description.txt",
      play_store_app_title: prj_folder + "/WordPress/metadata/title.txt",
      play_store_screenshot_1: prj_folder + "/WordPress/metadata/screenshot_1.txt",
      play_store_screenshot_2: prj_folder + "/WordPress/metadata/screenshot_2.txt",
      play_store_screenshot_3: prj_folder + "/WordPress/metadata/screenshot_3.txt",
      play_store_screenshot_4: prj_folder + "/WordPress/metadata/screenshot_4.txt",
      play_store_screenshot_5: prj_folder + "/WordPress/metadata/screenshot_5.txt",

      enhanced_app_store_screenshot_1: prj_folder + "/WordPress/metadata/enhanced_screenshot_1.html",
      enhanced_app_store_screenshot_2: prj_folder + "/WordPress/metadata/enhanced_screenshot_2.html",
      enhanced_app_store_screenshot_3: prj_folder + "/WordPress/metadata/enhanced_screenshot_3.html",
      enhanced_app_store_screenshot_4: prj_folder + "/WordPress/metadata/enhanced_screenshot_4.html",
      enhanced_app_store_screenshot_5: prj_folder + "/WordPress/metadata/enhanced_screenshot_5.html",
      enhanced_app_store_screenshot_6: prj_folder + "/WordPress/metadata/enhanced_screenshot_6.html",
      enhanced_app_store_screenshot_7: prj_folder + "/WordPress/metadata/enhanced_screenshot_7.html",
    }

    android_update_metadata_source(po_file_path: prj_folder + "/WordPress/metadata/PlayStoreStrings.po", 
      source_files: files, 
      release_version: options[:version])
  end 

  #####################################################################################
  # new_beta_release
  # -----------------------------------------------------------------------------------
  # This lane updates the release branch for a new beta release. It will update the
  # current release branch by default. If you want to update a different branch
  # (i.e. hotfix branch) pass the related version with the 'base_version' param
  # (example: base_version:10.6.1 will work on the 10.6.1 branch)
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane new_beta_release [skip_confirm:<skip confirm>] [base_version:<version>]
  #
  # Example:
  # bundle exec fastlane new_beta_release
  # bundle exec fastlane new_beta_release skip_confirm:true
  # bundle exec fastlane new_beta_release base_version:10.6.1
  #####################################################################################
  desc "Updates a release branch for a new beta release"
  lane :new_beta_release do | options |
    android_betabuild_prechecks(options)
    android_bump_version_beta()
    android_tag_build()
  end

  #####################################################################################
  # new_hotfix_release
  # -----------------------------------------------------------------------------------
  # This lane updates the release branch for a new hotix release. 
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane new_hotfix_release [skip_confirm:<skip confirm>] [version:<version>]
  #
  # Example:
  # bundle exec fastlane new_hotfix_release version:10.6.1
  # bundle exec fastlane new_hotfix_release skip_confirm:true version:10.6.1
  #####################################################################################
  desc "Creates a new hotfix branch from the given tag"
  lane :new_hotfix_release do | options |
    prev_ver = android_hotfix_prechecks(version_name: options[:version_name], skip_confirm: options[:skip_confirm])
    android_bump_version_hotfix(previous_version_name: prev_ver, version_name: options[:version_name], version_code: options[:version_code])
    android_tag_build(tag_alpha: false)
  end
  
  #####################################################################################
  # finalize_release
  # -----------------------------------------------------------------------------------
  # This lane finalize a release: updates store metadata and runs the release checks
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane finalize_release [skip_confirm:<skip confirm>] 
  #
  # Example:
  # bundle exec fastlane finalize_release 
  # bundle exec fastlane finalize_release skip_confirm:true 
  #####################################################################################
  desc "Updates store metadata and runs the release checks"
  lane :finalize_release do | options |
    android_finalize_prechecks(options)
    hotfix = android_current_branch_is_hotfix
    android_update_metadata(options) unless hotfix
    android_bump_version_final_release() unless hotfix
    version = android_get_release_version() unless hotfix
    download_metadata_strings(version: version["name"], build_number: version["code"]) unless hotfix
    android_tag_build(tag_alpha: false)

    # Wrap up
    removebranchprotection(repository:GHHELPER_REPO, branch: "release/#{version["name"]}")
    setfrozentag(repository:GHHELPER_REPO, milestone: version["name"], freeze: false)
    close_milestone(repository:GHHELPER_REPO, milestone: version["name"])
    create_new_milestone(repository:GHHELPER_REPO)
  end

  #####################################################################################
  # build_release
  # -----------------------------------------------------------------------------------
  # This lane builds the final release of the app and uploads it 
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane build_release [skip_confirm:<skip confirm>]
  #
  # Example:
  # bundle exec fastlane build_release 
  # bundle exec fastlane build_release skip_confirm:true 
  #####################################################################################
  desc "Builds and updates for distribution"
  lane :build_release do | options |
    android_build_prechecks(skip_confirm: options[:skip_confirm], 
      alpha: false,
      beta: false,
      final: true)
    android_build_preflight()
    
    # Create the file names
    version=android_get_release_version()
    build_bundle(version: version, flavor:"Vanilla", buildType: "release")
  end

  #####################################################################################
  # build_pre_releases
  # -----------------------------------------------------------------------------------
  # This lane builds the app it for both internal and external distribution 
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane build_pre_releases [skip_confirm:<skip confirm>]
  #
  # Example:
  # bundle exec fastlane build_pre_releases 
  # bundle exec fastlane build_pre_releases skip_confirm:true 
  #####################################################################################
  desc "Builds and updates for distribution"
  lane :build_pre_releases do | options |
    android_build_prechecks(skip_confirm: options[:skip_confirm], 
      alpha: true,
      beta: true,
      final: false)
    android_build_preflight()
    build_alpha(skip_prechecks: true, skip_confirm: options[:skip_confirm])
    build_beta(skip_prechecks: true, skip_confirm: options[:skip_confirm])
  end

  #####################################################################################
  # build_alpha
  # -----------------------------------------------------------------------------------
  # This lane builds the app it for internal testing  
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane build_alpha [skip_confirm:<skip confirm>]
  #
  # Example:
  # bundle exec fastlane build_alpha 
  # bundle exec fastlane build_alpha skip_confirm:true 
  #####################################################################################
  desc "Builds and updates for distribution"
  lane :build_alpha do | options |
    android_build_prechecks(skip_confirm: options[:skip_confirm], alpha: true) unless (options[:skip_prechecks])
    android_build_preflight() unless (options[:skip_prechecks])

    # Create the file names
    version=android_get_alpha_version()
    build_bundle(version: version, flavor:"Zalpha", buildType: "release")
  end

  #####################################################################################
  # build_beta
  # -----------------------------------------------------------------------------------
  # This lane builds the app it for internal testing  
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane build_beta [skip_confirm:<skip confirm>]
  #
  # Example:
  # bundle exec fastlane build_beta 
  # bundle exec fastlane build_beta skip_confirm:true 
  #####################################################################################
  desc "Builds and updates for distribution"
  lane :build_beta do | options |
    android_build_prechecks(skip_confirm: options[:skip_confirm], beta: true) unless (options[:skip_prechecks])
    android_build_preflight() unless (options[:skip_prechecks])

    # Create the file names
    version=android_get_release_version()
    build_bundle(version: version, flavor:"Vanilla", buildType: "release")
  end

  #####################################################################################
  # download_metadata_string 
  # -----------------------------------------------------------------------------------
  # This lane downloads the translated metadata (release notes,
  # app store strings, title, etc.) from GlotPress and updates the local files
  # -----------------------------------------------------------------------------------
  # Usage:
  # fastlane download_metadata_string build_number:<build_number> version:<version>
  #
  # Example:
  # fastlane download_metadata_string build_number:573 version:10.3
  #####################################################################################
  desc "Downloads translated metadata from GlotPress"
  lane :download_metadata_strings do |options| 
    values = options[:version].split('.')
    files = {
      "release_note_#{values[0]}#{values[1]}" => {desc: "changelogs/#{options[:build_number]}.txt", max_size: 0},
      play_store_promo: {desc:"short_description.txt", max_size: 80},
      play_store_desc: {desc:"full_description.txt", max_size: 0},
      play_store_app_title: {desc:"title.txt", max_size: 50}
    }

    delete_old_changelogs(build: options[:build_number])
    download_path=Dir.pwd + "/metadata/android"
    gp_downloadmetadata(project_url: "https://translate.wordpress.org/projects/apps/android/release-notes/", 
      target_files: files, 
      locales: SUPPORTED_LOCALES.map {| hsh | [ hsh[:glotpress], hsh[:google_play] ]},
      source_locale: "en-US",
      download_path: download_path)
    
    android_create_xml_release_notes(download_path: download_path, build_number: "#{options[:build_number]}", locales: SUPPORTED_LOCALES.map {| hsh | [ hsh[:glotpress], hsh[:google_play] ]})
    sh("git add #{download_path} && git commit -m \"Update metadata translations for #{options[:version]}\" && git push")
  end 

########################################################################
# Dependencies handling lanes
######################################################################## 
  main_strings_path = "./WordPress/src/main/res/values/strings.xml"
  libraries_strings_path = [
    {library: "Login Library", strings_path: "./libs/login/WordPressLoginFlow/src/main/res/values/strings.xml", exclusions: ["default_web_client_id"]}
  ]

  desc "Merge libraries strings files into the main app one"
  lane :localize_libs do | options |
    if (an_localize_libs(app_strings_path: main_strings_path, libs_strings_path: libraries_strings_path)) then
      UI.important("Your #{main_strings_path} has changed.")
      UI.input("Please, review the changes, commit them and press return to continue.")
    end
  end

  lane :validate_login_strings do | options |
    pr_number = options[:pr_number]
    pr_number = options[:pr_url].split('/').last unless options[:pr_url].nil?

    diff_url = nil
    if (pr_number.nil? == false)
      diff_url = "https://patch-diff.githubusercontent.com/raw/wordpress-mobile/WordPress-Android/pull/#{pr_number}.diff"
    end

    an_validate_lib_strings(app_strings_path: main_strings_path, libs_strings_path: libraries_strings_path, diff_url: diff_url) 
  end 

########################################################################
# Helper Lanes
########################################################################  
  desc "Get a list of pull request from `start_tag` to the current state"
  lane :get_pullrequests_list do | options |
    get_prs_list(repository:GHHELPER_REPO, start_tag:"#{options[:start_tag]}", report_path:"#{File.expand_path('~')}/wpandroid_prs_list.txt")
  end

  #####################################################################################
  # build_bundle
  # -----------------------------------------------------------------------------------
  # This lane builds an app bundle
  # -----------------------------------------------------------------------------------
  # Usage:
  # bundle exec fastlane build_bundle [skip_confirm:<skip confirm>]
  #####################################################################################
  desc "Builds an app bundle"
  lane :build_bundle do | options |
    # Create the file names
    version=options[:version]
    name="wpandroid-#{version["name"]}.aab"
    apk_name="wpandroid-#{version["name"]}-universal.apk"
    aab_file="org.wordpress.android-#{options[:flavor]}-#{options[:buildType]}.aab"
    output_dir="WordPress/build/outputs/bundle/"
    build_dir="build/"
    logfile_path="#{build_dir}build.log"

    # Intermediate Variables
    bundle_path = "#{output_dir}#{options[:flavor]}Release/#{aab_file}"

    # Build
    Dir.chdir("..") do
      UI.message("Cleaning branch...")
      sh("echo \"Cleaning branch\" >> #{logfile_path}")
      sh("./gradlew clean >> #{logfile_path} 2>&1")
      UI.message("Running lint...")
      sh("echo \"Running lint...\" >> #{logfile_path}")
      sh("./gradlew lint#{options[:flavor]}Release >> #{logfile_path} 2>&1")
      UI.message("Building #{version["name"]} / #{version["code"]} - #{aab_file}...")
      sh("echo \"Building #{version["name"]} / #{version["code"]} - #{aab_file}...\" >> #{logfile_path}")
      sh("./gradlew bundle#{options[:flavor]}Release >> #{logfile_path} 2>&1")

      UI.crash!("Unable to find a bundle at #{bundle_path}") unless File.file?(bundle_path)

      sh("cp -v #{bundle_path} #{build_dir}#{name} | tee -a #{logfile_path}")
      UI.message("Bundle ready: #{name}")
      sh("echo \"Bundle ready: #{name}\" >> #{logfile_path}")
      extract_universal_apk(bundle_path:"#{build_dir}#{name}", apk_path:"#{build_dir}#{apk_name}")
    end
    "#{build_dir}#{name}"
  end

#####################################################################################
# Private lanes
#####################################################################################
  private_lane :delete_old_changelogs do | options |
    Dir.glob("./metadata/android/*/").each do | folder |
      Dir["#{folder}changelogs/*"].each do | file |
        File.delete(file) if Integer(File.basename(file, ".*")) < Integer(options[:build]) rescue puts "Cannot delete file #{file}"
      end
    end
  end

  private_lane :extract_universal_apk do | options |
    bundle_path=options[:bundle_path]
    apk_path=options[:apk_path]
    temp_dir = Dir.mktmpdir()

    command = "source ./tools/gradle-functions.sh"
    command << "&& bundletool build-apks --bundle=\"#{bundle_path}\" \\
    --output=\"#{temp_dir}/universal.apks\" \\
    --mode=universal \\
    --ks=\"$(get_gradle_property gradle.properties storeFile)\" \\
    --ks-pass=\"pass:$(get_gradle_property gradle.properties storePassword)\" \\
    --ks-key-alias=\"$(get_gradle_property gradle.properties keyAlias)\" \\
    --key-pass=\"pass:$(get_gradle_property gradle.properties keyPassword)\""
    sh(command)

    sh("unzip \"#{temp_dir}/universal.apks\" -d \"#{temp_dir}\"")
    FileUtils.cp_r("#{temp_dir}/universal.apk", "#{apk_path}", remove_destination: true)  
    FileUtils.rm_rf("#{temp_dir}")
  end
end

